import os
import subprocess
from datetime import datetime
from src.modules.file_manager import FileManager
from src.utils.logger import log_info, log_error
from src.modules.media_processor import MediaProcessor

class FadeProcessor:
    """负责处理视频和音频的淡入淡出效果"""
    
    def __init__(self, startupinfo=None, logger=None):
        """初始化FadeProcessor
        
        :param startupinfo: 用于subprocess的startupinfo对象，默认为None
        :param logger: 用于日志记录的函数，默认为None
        """
        self.startupinfo = startupinfo
        self.logger = logger
        self.media_processor = MediaProcessor(startupinfo=startupinfo, logger=logger)
        self.file_manager = FileManager(logger=logger)
    
    def apply_video_fade_out(self, video_path, output_path=None, fade_duration=1.0):
        """为视频添加淡出效果
        
        :param video_path: 视频文件路径
        :param output_path: 输出视频路径，如果为None则自动生成
        :param fade_duration: 淡出效果持续时间（秒）
        :return: dict: 处理结果，包含output_path和success
        """
        try:
            # 获取视频时长
            video_duration = self.media_processor.get_media_duration(video_path)
            if video_duration is None:
                return {"success": False, "message": "无法获取视频时长"}
                
            # 计算淡出开始时间
            fade_start = max(0, video_duration - fade_duration)
            
            # 创建输出路径
            if output_path is None:
                base_name = os.path.basename(video_path)
                name, ext = os.path.splitext(base_name)
                temp_file = self.file_manager.create_temp_file(
                    prefix=f"{name}_",
                    suffix=f"_fadeout{ext}",
                )
                output_path = temp_file.path
            else:
                # 确保输出路径有正确的扩展名
                if not os.path.splitext(output_path)[1]:
                    # 如果没有扩展名，添加与输入文件相同的扩展名
                    _, ext = os.path.splitext(video_path)
                    output_path = output_path + ext
                    
            self._log_info(f"添加淡出效果，输出路径: {output_path}")
            
            # 构建命令：视频淡出到黑色
            cmd = [
                "ffmpeg",
                "-i", video_path,
                "-vf", f"fade=t=out:st={fade_start}:d={fade_duration}:color=black",
                "-af", f"afade=t=out:st={fade_start}:d={fade_duration}",
                "-c:v", "libx264",
                "-preset", "medium",
                "-crf", "18",
                "-y",
                output_path
            ]
            
            # 执行命令
            self._log_info(f"添加淡出效果，开始时间: {fade_start}秒，持续: {fade_duration}秒")
            self._log_info(f"执行命令: {' '.join(cmd)}")
            process = subprocess.run(
                cmd, 
                startupinfo=self.startupinfo,
                stderr=subprocess.PIPE,
                stdout=subprocess.PIPE,
                universal_newlines=True
            )
            
            if process.returncode == 0:
                self._log_info(f"视频淡出效果添加成功: {output_path}")
                import time
                time.sleep(0.2)  # 确保文件系统有时间更新
                return {"success": True, "output_path": output_path}
            else:
                self._log_error(f"添加淡出效果失败: {process.stderr}")
                return {"success": False, "message": f"添加淡出效果失败: {process.stderr[:200]}..."}
                
        except Exception as e:
            self._log_error(f"添加淡出效果时出错: {str(e)}")
            return {"success": False, "message": f"添加淡出效果时出错: {str(e)}"}

    def apply_audio_fade_out(self, audio_path, output_path=None, fade_duration=1.0):
        """为音频添加淡出效果
        
        :param audio_path: 音频文件路径
        :param output_path: 输出音频路径，如果为None则自动生成
        :param fade_duration: 淡出效果持续时间（秒）
        :return: dict: 处理结果，包含output_path和success
        """
        try:
            # 获取音频时长
            audio_duration = self.media_processor.get_media_duration(audio_path)
            if audio_duration is None:
                return {"success": False, "message": "无法获取音频时长"}
                
            # 计算淡出开始时间
            fade_start = max(0, audio_duration - fade_duration)
            
            # 创建输出路径
            if output_path is None:
                temp_dir = self.file_manager.create_temp_dir().path
                base_name = os.path.basename(audio_path)
                name, ext = os.path.splitext(base_name)
                output_path = os.path.join(temp_dir, f"{name}_fadeout{ext}")
                self.temp_files.append(output_path)
                
            # 构建命令：音频淡出
            cmd = [
                "ffmpeg",
                "-i", audio_path,
                "-af", f"afade=t=out:st={fade_start}:d={fade_duration}",
                "-c:a", "aac",
                "-b:a", "192k",
                "-y",
                output_path
            ]
            
            # 执行命令
            self._log_info(f"添加音频淡出效果，开始时间: {fade_start}秒，持续: {fade_duration}秒")
            process = subprocess.run(
                cmd, 
                startupinfo=self.startupinfo,
                stderr=subprocess.PIPE,
                stdout=subprocess.PIPE,
                universal_newlines=True
            )
            
            if process.returncode == 0:
                self._log_info(f"音频淡出效果添加成功: {output_path}")
                return {"success": True, "output_path": output_path}
            else:
                self._log_error(f"添加音频淡出效果失败: {process.stderr}")
                return {"success": False, "message": f"添加音频淡出效果失败: {process.stderr[:200]}..."}
                
        except Exception as e:
            self._log_error(f"添加音频淡出效果时出错: {str(e)}")
            return {"success": False, "message": f"添加音频淡出效果时出错: {str(e)}"}
    
    def _log_info(self, message):
        """记录信息级别日志"""
        if self.logger:
            self.logger(message)
        else:
            from src.utils.logger import log_info
            log_info(message)
    
    def _log_error(self, message):
        """记录错误级别日志"""
        if self.logger:
            self.logger(message, level="error")
        else:
            from src.utils.logger import log_error
            log_error(message)